package com.wkq.util

import android.content.Context
import com.tencent.mmkv.MMKV

/**
 * MMKV 工具类，用于简化 MMKV 的使用，支持多 ID 存储（多文件夹）
 *
 * @Author: wkq
 * @Time: 2025/4/9 12:07
 */
class MMKVUtil private constructor() {

    companion object {
        @Volatile
        private var instance: MMKVUtil? = null
        var initialized = false
        fun getInstance(): MMKVUtil {
            return instance ?: synchronized(this) {
                instance ?: MMKVUtil().also {
                    ensureMMKVInitialized()
                    instance = it
                }
            }
        }

        private fun ensureMMKVInitialized() {

            if (!initialized) {
                val context: Context = try {
                    AppCommonApplication()
                } catch (e: Exception) {
                    throw IllegalStateException("VoiceApplication.getInstance() 获取失败", e)
                }
                MMKV.initialize(context.applicationContext)
                initialized = true
            }
        }
    }

     fun getMMKV(id: String?, mode: Int = MMKV.SINGLE_PROCESS_MODE): MMKV {
        return if (id.isNullOrEmpty()) {
            MMKV.defaultMMKV() ?: throw IllegalStateException("MMKV not initialized")
        } else {
            MMKV.mmkvWithID(id, mode) ?: throw IllegalStateException("MMKV instance with id=$id not available")
        }
    }

    /** 编码并存储值，支持多种类型，可指定目录 ID */
    fun encode(key: String, value: Any, id: String? = null) {
        if (key.isEmpty()) return
        val mmkv = getMMKV(id)
        when (value) {
            is String -> mmkv.encode(key, value)
            is Int -> mmkv.encode(key, value)
            is Boolean -> mmkv.encode(key, value)
            is Long -> mmkv.encode(key, value)
            is Float -> mmkv.encode(key, value)
            is Double -> mmkv.encode(key, value)
            is ByteArray -> mmkv.encode(key, value)
            else -> throw IllegalArgumentException("Unsupported value type: ${value.javaClass.simpleName}")
        }
    }

    /** 解码获取值，支持泛型类型，可指定目录 ID */
    inline fun <reified T> decode(key: String, defaultValue: T, id: String? = null): T {
        if (key.isEmpty()) return defaultValue
        val mmkv = getMMKV(id)
        return when (T::class) {
            String::class -> mmkv.decodeString(key, defaultValue as? String) as T
            Int::class -> mmkv.decodeInt(key, defaultValue as Int) as T
            Boolean::class -> mmkv.decodeBool(key, defaultValue as Boolean) as T
            Long::class -> mmkv.decodeLong(key, defaultValue as Long) as T
            Float::class -> mmkv.decodeFloat(key, defaultValue as Float) as T
            Double::class -> mmkv.decodeDouble(key, defaultValue as Double) as T
            ByteArray::class -> mmkv.decodeBytes(key) as T? ?: defaultValue
            else -> throw IllegalArgumentException("Unsupported type: ${T::class.java.simpleName}")
        }
    }

    /** 删除单个键值，可指定目录 ID */
    fun removeValueForKey(key: String, id: String? = null) {
        if (key.isEmpty()) return
        getMMKV(id).removeValueForKey(key)
    }

    /** 删除多个 key，可指定目录 ID */
    fun removeValuesForKeys(keys: Array<out String>, id: String? = null) {
        if (keys.isEmpty()) return
        getMMKV(id).removeValuesForKeys(keys)
    }

    /** 清空所有存储，可指定目录 ID */
    fun clearAll(id: String? = null) {
        getMMKV(id).clearAll()
    }
}